﻿using System.Collections.Generic;
using GCTrackableRace.Interfaces;
using log4net;
using System;

namespace GcTrackableRace.ScoreCalculator
{
	public class ScoringEngine: IScoringEngine
	{
		public event EventHandler ProcessChange;

		private IEnumerable<ITrackable> _Trackables = new List<ITrackable>();

		public ScoringEngine(IGsakPersistence gsakPersistence, ILog log)
		{
			GsakPersistence = gsakPersistence;
			Log = log;
		}

		public void Process(IEnumerable<IRaceRule> rules)
		{
			Log.Info(String.Format("Process: Enter"));

			Log.Info(String.Format("Process: Calling GsakPersistence.GetAllTrackables()"));
			
			_Trackables = GsakPersistence.GetAllTrackables();

			foreach (var trackable in _Trackables)
			{
				EventHandler handler = ProcessChange;

				if (handler != null)
				{
					handler(this, new TrackableEventArgs(trackable.Code, "Processing ..."));
				}
				
				Log.Info(String.Format("Process: Processing Trackable '{0}'", trackable.Code));

				Log.Debug(String.Format("Process: Fetching all log entries for '{0}'", trackable.Code));
				
				var allTrackableLogs = GsakPersistence.GetAllTrackableLogs(trackable.Code);

				foreach (var rule in rules)
				{
					if (handler != null)
					{
						handler(this, new TrackableEventArgs(trackable.Code, "  " + rule.RuleName));
					}

					Log.Debug(String.Format("Process: Processing Rule '{0}' for trackable '{1}'", rule.RuleName, trackable.Code));

					rule.Process(trackable, allTrackableLogs);					
				}
			}
			
			Log.Info(String.Format("Process: Completed processing of all trackables"));
		}

		public IEnumerable<ITrackable> Trackables
		{
			get { return _Trackables; }
		}

		private IGsakPersistence GsakPersistence { get; set; }
		
		private ILog Log { get; set; }
	}
}
